package com.bsoft.gol.hcb.service.evaluation;

import com.bsoft.gol.hcb.dao.evaluation.*;
import com.bsoft.gol.hcb.utils.CommonUtils;
import com.bsoft.gol.hcb.utils.DateUtils;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import ctd.account.UserRoleToken;
import ctd.controller.exception.ControllerException;
import ctd.dictionary.Dictionary;
import ctd.dictionary.DictionaryItem;
import ctd.spring.boot.annotation.SsdevService;
import ctd.util.annotation.RpcService;
import hcn.base.DeptReg;
import hcn.base.Organization;
import hcn.base.evaluation.EvaluationDefine;
import hcn.base.evaluation.EvaluationItem;
import hcn.base.evaluation.EvaluationRecord;
import hcn.bean.UserVo;
import hcn.common.CodeDefinition;
import hcn.ods.OdsRegprepare;
import hcn.service.base.IEvaluationService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import pcn.enums.RoleIdEnum;
import pcn.sign.DoctInfo;
import pcn.vo.evaluation.GetDetailByIdVo;
import service.rpc.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * Created by zcj 2021年8月20日14:20:30 微服务接口改造
 * <p/>
 * 满意度评价服务
 */
@SsdevService("evaluation")
public class EvaluationService implements IEvaluationService {

    private Logger logger = LoggerFactory.getLogger(EvaluationService.class);
    @Autowired
    private EvaluationDefineDAO evaluationDefineDAO;
    @Autowired
    private EvaluationImpressDAO evaluationImpressDAO;
    @Autowired
    private EvaluationItemDAO evaluationItemDAO;
    @Autowired
    private EvaluationItemRecordDAO evaluationItemRecordDAO;
    @Autowired
    private EvaluationRecordDAO evaluationRecordDAO;

    @Autowired
    private DoctorInfoServiceIntf doctorInfoServiceIntf;
    @Autowired
    private RegistrationServiceIntf registrationServiceIntf;
    @Autowired
    private BaseUserManageUnitIntf baseUserManageUnitService;

    private final String FIRST_EVALUATION = "1";   //首评
    private final String ADD_EVALUATION = "2";     //追评
    private final Map<String, String> itemsMap = new HashMap<String, String>();

    private final String dicPath = "hcn.base.dictionary.doctorTitle";
    private List<DictionaryItem> items;


    @Autowired
    private DeptInfoServiceIntf deptInfoServiceIntf;
    @Autowired
    private OrganizationInfoIntf organizationInfoService;

    public EvaluationService() {
        itemsMap.put("lessMoney", "花钱少");
        itemsMap.put("benevolence", "有爱心");
        itemsMap.put("clinic", "多临床");
        itemsMap.put("goodEffect", "疗效好");
        itemsMap.put("attitude", "态度好");
        itemsMap.put("efficiency", "效率高");
        itemsMap.put("reply", "有效回复");
        itemsMap.put("bad", "差评");
        itemsMap.put("word", "有文字评价");
        itemsMap.put("addEvaluate", "有疗效评价");
    }

    /**
     * 添加满意度评价业务定义
     *
     * @param define
     */
    @Override
    @RpcService
    public Integer addBusinessType(EvaluationDefine define) throws ControllerException {
        logger.info("addSatisfactionType|define:{}", define);
        if (define == null || StringUtils.isBlank(define.getBusinessName())
                || StringUtils.isBlank(define.getBusinessType())) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "orgId and businessType and businessName can not be null");
        }
        EvaluationDefine dbDefine = evaluationDefineDAO.getByBusinessType(define.getBusinessType(),define.getOccasion());
        if (dbDefine != null) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "the businessType " + define.getBusinessType() + " exists");
        }
//        define.setStatus('1');
        define.setTenantId(UserRoleToken.getCurrentTenantId());
        EvaluationDefine d = evaluationDefineDAO.save(define);
        return d.getId();
    }


    /**
     * 添加满意度评价项目类型
     *
     * @param item
     */
    @Override
    @RpcService
    public void addEvaluationItem(EvaluationItem item) throws ControllerException {
        logger.info("addEvaluationItem|item:{}", item);
        if (item == null || item.getDefineId() == 0 || StringUtils.isBlank(item.getContent())) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "defineId and content can not be null");
        }
        if (item.getOrderNum() == 0) {
            item.setOrderNum(9);
        }
        item.setTenantId(UserRoleToken.getCurrentTenantId());
        evaluationItemDAO.save(item);
    }

    /**
     * 评论/追评
     *
     * @param map (key:[id,mpiId,orgId,businessType,businessId,doctorId,content,
     *            evaluationType,userId,itemList(itemId,level),impressList])
     * @throws ControllerException
     */
    @Override
    @RpcService
    public void evaluateDoct(Map<String, Object> map) throws ControllerException {
        logger.info("evaluateDoct|map:{}", map);

        //追评
        if (map.get("id") != null && ((int) map.get("id")) != 0) {
            if (map.get("userId") == null || map.get("itemList") == null) {
                throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "mpiId and orgId and businessType and businessId and doctorId and evaluationType and userId can not be null");
            }
            Date date = new Date();
            EvaluationRecord record = new EvaluationRecord();
            if (map.get("addContent") != null && StringUtils.isNotBlank(String.valueOf(map.get("addContent")))) {
                record.setAddContent(String.valueOf(map.get("addContent")));
            }
            record.setId(Integer.parseInt(String.valueOf(map.get("id"))));
            record.setAddDt(date);
            record.setAddUserId(String.valueOf(map.get("userId")));
            record.setTenantId(UserRoleToken.getCurrentTenantId());
            List<Map<String, Integer>> toSaveItems = (List<Map<String, Integer>>) map.get("itemList");
            evaluationRecordDAO.saveRecord(record, toSaveItems, date);
            return;
        }

        //第一次评价
        if (map.get("mpiId") == null || map.get("orgId") == null || map.get("businessType") == null
                || map.get("userId") == null || map.get("businessId") == null
                || (map.get("doctorId") == null && map.get("localDoctorId") == null) || map.get("itemList") == null
                ||(map.get("occasion")==null && map.get("accasion")==null)) {//时间问题先加字段，后期改掉
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "mpiId and orgId and businessType and businessId and doctorId and evaluationType and userId and occasion can not be null");
        }
        Date date = new Date();
        String accosion ="";
        //时间问题先加字段，后期改掉追评或首评字段
        if (CommonUtils.isNotEmpty(map.get("accasion"))){
            accosion = (String)map.get("accasion");
        }
        if (CommonUtils.isNotEmpty(map.get("occasion"))){
            accosion = (String)map.get("occasion");
        }
        EvaluationDefine dbDefine = evaluationDefineDAO.getByBusinessType(String.valueOf(map.get("businessType")),accosion);
        if (dbDefine == null) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "the businessType " + String.valueOf(map.get("businessType")) + " not exist");
        }
        EvaluationRecord record = new EvaluationRecord();
        String doctorId = "";
        record.setDefineId(dbDefine.getId());
        record.setMpiId(String.valueOf(map.get("mpiId")));
        record.setOrgId(String.valueOf(map.get("orgId")));

        Organization organization = organizationInfoService.getOrgDetailByOrgId(map.get("orgId").toString());
        if(organization!=null) {
            record.setOrgName(organization.getFullName());
        }

        record.setBusinessType(String.valueOf(map.get("businessType")));
        record.setBusinessId(Integer.parseInt(String.valueOf(map.get("businessId"))));
        record.setTargetType(RoleIdEnum.DOCTOR.title());
        record.setTenantId(UserRoleToken.getCurrentTenantId());
        //app传进来的doctorId与localDoctorId二选其一
        if (map.get("doctorId") != null) {
            doctorId = String.valueOf(map.get("doctorId"));
        }
//         if(map.get("localDoctorId")!=null){
//        	 doctorId=String.valueOf(map.get("localDoctorId"));
//         }
        record.setDoctorId(doctorId);

        DoctInfo doctInfo = doctorInfoServiceIntf.getDocInfo(doctorId);
        if(doctInfo!=null){
            record.setDoctName(doctInfo.getName());
            record.setSex(doctInfo.getSex());
            record.setLevel(doctInfo.getLevel());
        }

        try {
            OdsRegprepare odsRegprepare =registrationServiceIntf.getOdsRegprepareById(Integer.parseInt(String.valueOf(map.get("businessId"))));
            record.setWorkDate(odsRegprepare.getWorkDate());
            record.setRegDeptId(odsRegprepare.getRegDeptId());
            record.setRegDeptName(odsRegprepare.getRegDeptName());
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (map.get("firstContent") != null && StringUtils.isNotBlank(String.valueOf(map.get("firstContent")))) {
            record.setFirstContent(String.valueOf(map.get("firstContent")));
        }
        record.setFirstFlag("1");
        record.setFirstDt(date);
        record.setFirstUserId(String.valueOf(map.get("userId")));
        List<Map<String, Integer>> toSaveItems = (List<Map<String, Integer>>) map.get("itemList");
        evaluationRecordDAO.saveRecord(record, toSaveItems, date);
    }


    /**
     * 保存医生印象
     *
     * @param map (orgId,doctorId,userId,impressList,businessId)
     * @throws ControllerException
     */
    @Override
    @RpcService
    public void saveImpresses(Map<String, Object> map) throws ControllerException {
        logger.info("saveImpresses|map:{}", map);
        if (map.get("orgId") == null || (map.get("doctorId") == null) || map.get("businessId") == null
                || map.get("userId") == null || map.get("impressList") == null
                || Integer.parseInt(String.valueOf(map.get("businessId"))) == 0) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "orgId and doctorId and userId and impressList and businessId can not be null");
        }
//        if(map.get("localDoctorId")!=null &&map.get("doctorId")==null){
//        	String localDoctorId=String.valueOf(map.get("localDoctorId"));
//        	DoctorOrgs doctorOrgs=orgDoctorsDAO.getOrgDoctorsLocalDoctorId(localDoctorId);
//        	String doctId=doctorOrgs.getDoctorId();
//        	//把localDoctorId转成doctorId
//        	map.put("localDoctorId", doctId);
//        }
        evaluationImpressDAO.saveImpresses(map);
    }

    @Override
    @RpcService
    public  List<Map<String, Object>> queryImpressesById(String doctorId, int start, int limit) throws ControllerException {
        if (doctorId == null || doctorId.isEmpty()) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "Cannot find doctorId ...{}");
        }
        return evaluationImpressDAO.getDoctImpresses(doctorId, start, limit);
    }

    /**
     * 查询医生印象
     *
     * @param map (key:[doctId,userId,businessId,pageStart,pageLimit])
     * @return
     * @throws ControllerException
     */
    @Override
    @RpcService
    public Map<String, Object> queryImpressesByDoctId(Map<String, Object> map) throws ControllerException {
        logger.info("queryImpressesByDoctId|map:{}", map);
        if ((map.get("doctId") == null) || map.get("userId") == null || map.get("businessId") == null
                || ((StringUtils.isBlank(String.valueOf(map.get("doctId")))))
                || (StringUtils.isBlank(String.valueOf(map.get("userId"))))
                || Integer.parseInt(String.valueOf(map.get("businessId"))) == 0) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "doctId and userId and businessId can not be null");
        }
        int start = 0;
        int limit = 15;
        String doctId = "";
        if (map.get("doctId") != null) {
            doctId = String.valueOf(map.get("doctId"));
        }
//        if(map.get("localDoctorId") !=null){
//        	String localDoctorId=String.valueOf(map.get("localDoctorId"));
//        	DoctorOrgs doctorOrgs=orgDoctorsDAO.getOrgDoctorsLocalDoctorId(localDoctorId);
//        	doctId=doctorOrgs.getDoctorId();
//        }
        if (map.get("pageStart") != null && map.get("pageLimit") != null) {
            int pageSize = Integer.parseInt(String.valueOf((map.get("pageStart"))));
            limit = Integer.parseInt(String.valueOf(map.get("pageLimit")));
            start = (pageSize - 1) * limit;
        }
        int businessId = Integer.parseInt(String.valueOf(map.get("businessId")));
        List<String> orgIdList = organizationInfoService.queryOrgIdListByCloudId(UserRoleToken.getCurrentTenantId());
        List<String[]> dbContents = null;
        List<Object[]> dbImpresses = null;
        long userEvaluateCount = 0;
        if(CommonUtils.isNotEmpty(orgIdList)){
            dbContents = evaluationImpressDAO.findContentsByDoctId(doctId,orgIdList);
            dbImpresses = evaluationImpressDAO.findDoctImpresses(doctId, start, limit,orgIdList);
            userEvaluateCount = evaluationImpressDAO.getCountByUserId(String.valueOf(map.get("userId")), doctId, businessId,orgIdList);
        }
        Map<String, Object> resultMap = new HashMap<String, Object>();
        List<String> result = new ArrayList<String>();
        if (dbImpresses != null && dbImpresses.size() > 0) {
            for (int i = 0; i < dbImpresses.size(); ++i) {
                Object[] obj = dbImpresses.get(i);
                String impress = String.valueOf(obj[0]);
                String sum = String.valueOf(obj[1]);
                if (!"1".equals(sum)) {
                    result.add(impress + "(" + sum + ")");
                } else {
                    result.add(impress);
                }
            }
            resultMap.put("impressList", result);
        }
        if (dbContents != null) {
            resultMap.put("count", dbContents.size());
        }
        resultMap.put("isEvaluated", (userEvaluateCount == 0) ? false : true);
        return resultMap;
    }


    /**
     * 查询评价列表
     *
     * @param map (key:[userId,doctName])
     * @return
     * @throws ControllerException
     */
    @Override
    @RpcService
    public List<Map<String, Object>> queryEvaluateList(Map<String, String> map) throws ControllerException {
        logger.info("queryEvaluateList|map:{}", map);
        String userId = "";
        try {
            UserVo userIdByOnline = baseUserManageUnitService.getUserIdByOnline();
            if(null != userIdByOnline){
                userId = userIdByOnline.getUserId();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (CommonUtils.isEmpty(userId)) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "userId is null");
        }
        List<Object[]> evaluatedList = null;
        if (StringUtils.isNotBlank(map.get("doctName"))) {
            evaluatedList = evaluationRecordDAO.findEvaluateListByUserIdAndDoctName(userId, map.get("doctName"));
        } else {
            evaluatedList = evaluationRecordDAO.findEvaluateListByUserId(userId);
        }
        List<Map<String, Object>> result = null;
        if (evaluatedList != null && evaluatedList.size() > 0) {
            result = new ArrayList<Map<String, Object>>();
            SimpleDateFormat sp = new SimpleDateFormat("yyyy-MM-dd");
            for (int i = 0; i < evaluatedList.size(); ++i) {
                Map<String, Object> resultMap = new HashMap<String, Object>();
                Object[] obj = evaluatedList.get(i);
                if (obj[8] == null) {
                    continue;
                }
                resultMap.put("orgName", obj[0]);
                resultMap.put("orgId", obj[8]);
                resultMap.put("doctName", obj[1]);
                resultMap.put("regDt", sp.format(obj[2]));
                resultMap.put("id", obj[3]);
                resultMap.put("businessId", obj[9]);
                resultMap.put("source", String.valueOf(obj[5]));
                if (obj[4] != null && StringUtils.isNotBlank(String.valueOf(obj[4]))) {
                    setDoctLevel(resultMap, String.valueOf(obj[4]));
                }
                if ("1".equals(String.valueOf(obj[7]))) {
                    resultMap.put("evaluationType", ADD_EVALUATION);
                } else if ("1".equals(String.valueOf(obj[6]))) {
                    resultMap.put("evaluationType", FIRST_EVALUATION);
                }
                result.add(resultMap);
            }
        }
        return result;
    }


    /**
     * 查看详情
     *
     * @param id
     * @return
     * @throws ControllerException
     */
    @Override
    @RpcService
    public Map<String, Object> queryById(int id) throws ControllerException {
        logger.info("queryById|id:{}", id);
        if (id == 0) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "id is null");
        }
        GetDetailByIdVo dbSat = evaluationRecordDAO.getDetailById(id);
        if (dbSat == null) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "id=" + id + " and the record not exsits");
        }
        List<Object[]> itemList = evaluationItemRecordDAO.findDetailByRecordId(id);

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("doctName", dbSat.getDoctName());
        result.put("doctId", dbSat.getDoctorId());
        result.put("regDt", DateUtils.toStringForYYYYMMdd(dbSat.getWorkDate()));
        result.put("id", dbSat.getId());
        result.put("firstContent", dbSat.getFirstContent());
        if (dbSat.getFirstContent()!= null) {
            result.put("addContent", dbSat.getAddContent());
        }
        if (CommonUtils.isNotEmpty(dbSat.getLevel())) {
            setDoctLevel(result, String.valueOf(dbSat.getLevel()));
        }
        String orgId = dbSat.getOrgId();
        String regDeptId = dbSat.getRegDeptId();
        result.put("doctSex", dbSat.getSex());
        DeptReg deptReg = deptInfoServiceIntf.getDeptRegByRegDeptId(orgId, regDeptId);
        if (deptReg != null && StringUtils.isNotBlank(deptReg.getRegDeptName())) {
            result.put("deptName", deptReg.getRegDeptName());
        }else{
            result.put("deptName", dbSat.getRegDeptName());
        }

        if (itemList != null && itemList.size() > 0) {
            List<Map<String, Object>> itemResult = new ArrayList<Map<String, Object>>();
            for (int i = 0; i < itemList.size(); ++i) {
                Object[] items = itemList.get(i);
                Map<String, Object> itemMap = new HashMap<String, Object>();
                itemMap.put("itemId", Integer.parseInt(String.valueOf(items[2])));
                itemMap.put("content", String.valueOf(items[0]));
                itemMap.put("level", Integer.parseInt(String.valueOf(items[1])));
                itemMap.put("occasion", String.valueOf(items[3]));
                itemResult.add(itemMap);
            }
            result.put("itemList", itemResult);
        }
        return result;

    }


    /**
     * 医生评价列表
     *
     * @param map (key:[doctId,pageStart,pageLimit,type(all,regprepare,consult),condition])
     * @return
     * @throws ControllerException
     */
    @Override
    @RpcService
    public Map<String, Object> queryListFromDoct(Map<String, String> map) throws ControllerException {
        logger.info("queryListFromDoct|map:{}", map);
        if (StringUtils.isBlank(map.get("doctId"))) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "doctorId is null");
        }
        int start = 0;
        int limit = 50;
        String doctId = String.valueOf(map.get("doctId"));
        if (map.get("pageStart") != null && map.get("pageLimit") != null) {
            int pageSize = Integer.parseInt(String.valueOf((map.get("pageStart"))));
            limit = Integer.parseInt(String.valueOf(map.get("pageLimit")));
            start = (pageSize - 1) * limit;
        }
        List<Object[]> dbData = null;
        if (StringUtils.isBlank(map.get("type")) || "all".equals(map.get("type"))) {
            if (StringUtils.isBlank(map.get("condition")) || "all".equals(map.get("condition"))
                    || "bad".equals(map.get("condition"))) {
                dbData = evaluationRecordDAO.findAllListFromDoct(doctId, start, limit);
            } else {
                dbData = queryListFromDoct(map.get("condition"), doctId, null, start, limit);
            }
        } else {
            if (StringUtils.isBlank(map.get("condition")) || "all".equals(map.get("condition"))
                    || "bad".equals(map.get("condition"))) {
                dbData = evaluationRecordDAO.findListFromDoctByBusinessType(doctId, map.get("type"), start, limit);
            } else {
                dbData = queryListFromDoct(map.get("condition"), doctId, map.get("type"), start, limit);
            }
        }

        List<Map<String, Object>> resultDetail = null;
        Map<String, Object> resultMap = null;
        Map<String, Object> countMap = null;       //标题统计详情
        Map<String, Object> listDetailMap = null;  //列表详情
        final SimpleDateFormat sp = new SimpleDateFormat("yyyy-MM-dd");
        Integer[] recordIds = null;
        int allSize = 0;
        if (dbData != null && dbData.size() > 0) {
            resultDetail = new ArrayList<Map<String, Object>>();
            recordIds = new Integer[dbData.size()];
            countMap = new HashMap<String, Object>();
            resultMap = new HashMap<String, Object>();
            listDetailMap = new HashMap<String, Object>();
            resultMap.put("total", countMap);
            listDetailMap.put("list", resultDetail);
            resultMap.putAll(listDetailMap);
            allSize = dbData.size();
            for (int i = 0; i < dbData.size(); ++i) {
                Map<String, Object> detailMap = new HashMap<String, Object>();
                Object[] obj = dbData.get(i);
                int id = Integer.parseInt(String.valueOf(obj[0]));
                String name = String.valueOf(obj[1]).substring(0, 1) + "**";
                recordIds[i] = id;

                //统计评论有文字和有追评的记录数
                if ((obj[2] != null && StringUtils.isNotBlank(String.valueOf(obj[2])))
                        || (obj[3] != null && StringUtils.isNotBlank(String.valueOf(obj[3])))) {
                    if (countMap.get("word") == null) {
                        countMap.put("word", 1);
                    } else {
                        int wordCount = (Integer) countMap.get("word");
                        countMap.put("word", ++wordCount);
                    }
                }
                if (obj[5] != null) {
                    if (countMap.get("addEvaluate") == null) {
                        countMap.put("addEvaluate", 1);
                    } else {
                        int wordCount = (Integer) countMap.get("addEvaluate");
                        countMap.put("addEvaluate", ++wordCount);
                    }
                }

                if ("bad".equals(map.get("condition"))) {
                    detailMap.put("addFlag", (obj[5] != null) ? "1" : "0");
                }

                try {
                    Date firstDt = sp.parse(sp.format(obj[4]));
                    detailMap.put("id", id);
                    detailMap.put("name", name);
                    detailMap.put("source", obj[6]);
                    if (obj[5] == null) {
                        detailMap.put("evaluationDate", sp.format(obj[4]));
                        if (obj[2] != null) {
                            detailMap.put("content", obj[2]);
                        }
                        resultDetail.add(detailMap);
                    } else {
                        Date addDt = sp.parse(sp.format(obj[5]));
                        if (addDt.after(firstDt)) {
                            detailMap.put("evaluationDate", sp.format(obj[5]));
                            if (obj[3] != null) {
                                detailMap.put("content", obj[3]);
                            }
                            resultDetail.add(detailMap);
                        } else {
                            detailMap.put("evaluationDate", sp.format(obj[4]));
                            if (obj[2] != null) {
                                detailMap.put("content", obj[2]);
                            }
                            resultDetail.add(detailMap);
                        }
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            countMap.put("count", dbData.size());
            if (countMap.get("word") == null) {
                countMap.put("word", "有文字评价");
            } else {
                countMap.put("word", "有文字评价(" + countMap.get("word") + ")");
            }
            if (countMap.get("addEvaluate") == null) {
                countMap.put("addEvaluate", "有疗效评价");
            } else {
                countMap.put("addEvaluate", "有疗效评价(" + countMap.get("addEvaluate") + ")");
            }
        }


        //查询评分列表
        if (recordIds != null) {
            List<Object[]> itemRecords = evaluationItemRecordDAO.findListByRecordIds(recordIds);
            if (itemRecords != null && itemRecords.size() > 0) {
                if ("bad".equals(map.get("condition"))) {
                    Multimap<Integer, Integer> recordIdTmpMap = ArrayListMultimap.create();
                    for (int i = 0; i < itemRecords.size(); ++i) {
                        Object[] itemRecord = itemRecords.get(i);
                        int level = Integer.parseInt(String.valueOf(itemRecord[1]));
                        int recordId = Integer.parseInt(String.valueOf(itemRecord[2]));
                        recordIdTmpMap.put(recordId, level);
                    }
                    Set<Integer> recordIdSet = recordIdTmpMap.keySet();

                    //差评查询变量
                    List<Integer> badRecordId = new ArrayList<Integer>();
                    for (Integer recordId : recordIdSet) {
                        int levelSum = 0;
                        Collection<Integer> levelTmp = recordIdTmpMap.get(recordId);
                        for (Integer levelInt : levelTmp) {
                            levelSum += levelInt;
                        }
                        //计算差评数
                        if (Math.round(levelSum / levelTmp.size()) <= 2) {
                            if ("bad".equals(map.get("condition"))) {
                                badRecordId.add(recordId);
                            }
                        }
                    }
                    if (badRecordId.size() > 0) {

                        for (Iterator<Object[]> iterator = itemRecords.iterator(); iterator.hasNext(); ) {
                            Object[] obj = iterator.next();
                            Integer recordId = Integer.parseInt(String.valueOf(obj[2]));
                            if (!badRecordId.contains(recordId)) {
                                iterator.remove();
                            }
                        }
                        int wordCount = 0;
                        int addEvaluateCount = 0;
                        for (Iterator<Map<String, Object>> iterator = resultDetail.iterator(); iterator.hasNext(); ) {
                            Map<String, Object> next = iterator.next();
                            Integer dbRecord = (Integer) next.get("id");
                            if (!badRecordId.contains(dbRecord)) {
                                iterator.remove();
                            } else {
                                if (next.get("content") != null) {
                                    wordCount++;
                                }
                                if ("1".equals(next.get("addFlag"))) {
                                    addEvaluateCount++;
                                }
                            }
                        }
                        allSize = resultDetail.size();
                        countMap.put("count", allSize);

                        if (wordCount == 0) {
                            countMap.put("word", "有文字评价");
                        } else {
                            countMap.put("word", "有文字评价(" + wordCount + ")");
                        }
                        if (addEvaluateCount == 0) {
                            countMap.put("addEvaluate", "有疗效评价");
                        } else {
                            countMap.put("addEvaluate", "有疗效评价(" + addEvaluateCount + ")");
                        }
                    }
                }


                Multimap<String, Integer> itemTmpMap = ArrayListMultimap.create();
                Multimap<Integer, Integer> recordIdTmpMap = ArrayListMultimap.create();
                for (int i = 0; i < itemRecords.size(); ++i) {
                    Object[] itemRecord = itemRecords.get(i);
                    String content = String.valueOf(itemRecord[0]);
                    int level = Integer.parseInt(String.valueOf(itemRecord[1]));
                    int recordId = Integer.parseInt(String.valueOf(itemRecord[2]));
                    itemTmpMap.put(content, level);
                    recordIdTmpMap.put(recordId, level);
                }
                //统计好评率,差评
                int goodEvaluateSum = 0;
                int badSum = 0;
                Set<Integer> recordIdSet = recordIdTmpMap.keySet();


                for (Integer recordId : recordIdSet) {
                    int levelSum = 0;
                    Collection<Integer> levelTmp = recordIdTmpMap.get(recordId);
                    for (Integer levelInt : levelTmp) {
                        levelSum += levelInt;
                    }
                    //计算好评数
                    if (Math.round(levelSum / levelTmp.size()) >= 4) {
                        goodEvaluateSum++;
                    }
                    //计算差评数
                    if (Math.round(levelSum / levelTmp.size()) <= 2) {
                        badSum++;
                    }
                }


                double goodEvaluateSumDb = goodEvaluateSum;
                int goodEvaluateRate = (int) ((goodEvaluateSumDb / allSize) * 100);
                countMap.put("goodEvaluateRate", goodEvaluateRate + "%");
                countMap.put("badEvaluate", (badSum == 0) ? "差评" : "差评(" + badSum + ")");

                int lessMoneyFullMarks = 0;
                int benevolenceFullMarks = 0;
                int clinicFullMarks = 0;
                int goodEffectFullMarks = 0;
                Set<String> itemContents = itemTmpMap.keySet();
                for (String content : itemContents) {
                    Collection<Integer> levels = itemTmpMap.get(content);
                    for (Integer levelInt : levels) {
                        if (levelInt == 5) {
                            if (content.contains("花钱少")) {
                                lessMoneyFullMarks++;
                            } else if (content.contains("有爱心")) {
                                benevolenceFullMarks++;
                            } else if (content.contains("多临床")) {
                                clinicFullMarks++;
                            } else if (content.contains("疗效好")) {
                                goodEffectFullMarks++;
                            } else if (content.contains("态度好")) {
                                goodEffectFullMarks++;
                            }
                        }
                    }
                    if (content.contains("花钱少")) {
                        countMap.put("lessMoney", (lessMoneyFullMarks == 0) ? "花钱少" : "花钱少(" + lessMoneyFullMarks + ")");
                    } else if (content.contains("有爱心")) {
                        countMap.put("benevolence", (benevolenceFullMarks == 0) ? "有爱心" : "有爱心(" + benevolenceFullMarks + ")");
                    } else if (content.contains("多临床")) {
                        countMap.put("clinic", (clinicFullMarks == 0) ? "多临床" : "多临床(" + clinicFullMarks + ")");
                    } else if (content.contains("疗效好")) {
                        countMap.put("goodEffect", (goodEffectFullMarks == 0) ? "疗效好" : "疗效好(" + goodEffectFullMarks + ")");
                    }
                }

            }
        }


        if (resultDetail != null) {
            Collections.sort(resultDetail, new Comparator<Map<String, Object>>() {
                @Override
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    try {
                        Date date1 = sp.parse(String.valueOf(o1.get("evaluation")));
                        Date date2 = sp.parse(String.valueOf(o2.get("evaluation")));
                        if (date2.after(date1)) {
                            return 1;
                        } else if (date2.before(date1)) {
                            return -1;
                        } else {
                            return 0;
                        }
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    return 0;
                }
            });
        }
        return resultMap;
    }


    /**
     * 医生查看详情
     *
     * @param id
     * @return
     * @throws ControllerException
     */
    @Override
    @RpcService
    public Map<String, Object> queryByIdFromDoct(int id) throws ControllerException {
        logger.info("queryById|id:{}", id);
        if (id == 0) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "id is null");
        }
        GetDetailByIdVo dbSat = evaluationRecordDAO.getDetailById(id);
        if (dbSat == null) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "id=" + id + " and the record not exsits");
        }
        List<Object[]> itemList = evaluationItemRecordDAO.findDetailByRecordId(id);

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("firstContent", dbSat.getFirstContent());
        if (CommonUtils.isNotEmpty(dbSat.getFirstContent())) {
            result.put("addContent", dbSat.getAddContent());
        }

        if (itemList != null && itemList.size() > 0) {
            List<Map<String, Object>> itemResult = new ArrayList<Map<String, Object>>();
            for (int i = 0; i < itemList.size(); ++i) {
                Object[] items = itemList.get(i);
                Map<String, Object> itemMap = new HashMap<String, Object>();
                itemMap.put("content", String.valueOf(items[0]));
                itemMap.put("level", Integer.parseInt(String.valueOf(items[1])));
                itemMap.put("occasion", String.valueOf(items[3]));
                itemResult.add(itemMap);
            }
            result.put("itemList", itemResult);
        }
        return result;

    }


    /**
     * 通过业务id查询评价状态
     *
     * @param businessId
     * @return true：已评价，false:未评价
     */
    @Override
    @RpcService
    public boolean checkFlagByBusinessId(int businessId) throws ControllerException {
        logger.info("checkFlagByBusinessId|businessId:{}", businessId);
        if (businessId == 0) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "businessId is null");
        }
        List<EvaluationRecord> byBusinessId = evaluationRecordDAO.findByBusinessId(businessId);
        if (byBusinessId != null && byBusinessId.size() > 0 && "1".equals(byBusinessId.get(0).getFirstFlag())) {
            return true;
        }
        return false;
    }

    /**
     * 通过业务类型查询评价项目
     *
     * @param businessType
     * @throws ControllerException
     * @param occasion 时机 0首评,1:追评
     * @param status 启用标志
     */
    @Override
    @RpcService
    public List<EvaluationItem> queryItemsByBusinessType(String businessType,String occasion,String status) throws ControllerException {
        logger.info("queryItemsByBusinessType|businessType:{}", businessType);
        if (StringUtils.isBlank(businessType)) {
            throw new ControllerException(CodeDefinition.SATISFACTION_EVALUATE, "businessType can not be null");
        }
        // 1:启用评价时机
        if(StringUtils.isNotEmpty(status) && "1".equals(status)){
            return evaluationItemDAO.findAddListByBusinessType(businessType,occasion);
        }else{
            return evaluationItemDAO.findListByBusinessType(businessType);
        }
    }

    /**
     * 查询医生被评价列表
     *
     * @param condition
     * @param doctId
     * @param businessType
     * @param start
     * @param limit
     * @return
     */
    private List<Object[]> queryListFromDoct(String condition, String doctId, String businessType, int start, int limit) {
        List<Object[]> dbData = null;
        switch (condition) {
            case "word"://有文字
                if (businessType != null) {
                    dbData = evaluationRecordDAO.findListFromDoctByWordAndBusinessType(doctId, businessType, start, limit);
                } else {
                    dbData = evaluationRecordDAO.findListFromDoctByWord(doctId, start, limit);
                }
                break;
            case "addEvaluate"://有疗效评价
                if (businessType != null) {
                    dbData = evaluationRecordDAO.findListFromDoctHasAddEvaluationAndBusinessType(doctId, businessType, start, limit);
                } else {
                    dbData = evaluationRecordDAO.findListFromDoctHasAddEvaluation(doctId, start, limit);
                }
                break;
            case "lessMoney"://花钱少
                if (businessType != null) {
                    dbData = evaluationRecordDAO.findListFromDoctByItemAndBusinessType(doctId, itemsMap.get(condition) + "%", businessType, start, limit);
                } else {
                    dbData = evaluationRecordDAO.findListFromDoctByItem(doctId, itemsMap.get(condition) + "%", start, limit);
                }
                break;
            case "benevolence"://有爱心
                if (businessType != null) {
                    dbData = evaluationRecordDAO.findListFromDoctByItemAndBusinessType(doctId, itemsMap.get(condition) + "%", businessType, start, limit);
                } else {
                    dbData = evaluationRecordDAO.findListFromDoctByItem(doctId, itemsMap.get(condition) + "%", start, limit);
                }
                break;
            case "clinic"://多临床
                if (businessType != null) {
                    dbData = evaluationRecordDAO.findListFromDoctByItemAndBusinessType(doctId, itemsMap.get(condition) + "%", businessType, start, limit);
                } else {
                    dbData = evaluationRecordDAO.findListFromDoctByItem(doctId, itemsMap.get(condition) + "%", start, limit);
                }
                break;
            case "goodEffect"://疗效好
                if (businessType != null) {
                    dbData = evaluationRecordDAO.findListFromDoctByItemAndBusinessType(doctId, itemsMap.get(condition) + "%", businessType, start, limit);
                } else {
                    dbData = evaluationRecordDAO.findListFromDoctByItem(doctId, itemsMap.get(condition) + "%", start, limit);
                }
                break;
            case "attitude"://态度好
                if (businessType != null) {
                    dbData = evaluationRecordDAO.findListFromDoctByItemAndBusinessType(doctId, "态度好%", businessType, start, limit);
                } else {
                    dbData = evaluationRecordDAO.findListFromDoctByItem(doctId, "态度好%", start, limit);
                }
                break;
            case "efficiency"://效率高
                if (businessType != null) {
                    dbData = evaluationRecordDAO.findListFromDoctByItemAndBusinessType(doctId, "效率高%", businessType, start, limit);
                } else {
                    dbData = evaluationRecordDAO.findListFromDoctByItem(doctId, "效率高%", start, limit);
                }
                break;
            case "reply"://有回复
                if (businessType != null) {
                    dbData = evaluationRecordDAO.findListFromDoctByItemAndBusinessType(doctId, "%回复%", businessType, start, limit);
                } else {
                    dbData = evaluationRecordDAO.findListFromDoctByItem(doctId, "%回复%", start, limit);
                }
                break;
            case "bad"://差评
                if (businessType != null) {
                    dbData = evaluationRecordDAO.findListFromDoctByLevelAndBusinessType(doctId, 2, businessType, start, limit);
                } else {
                    dbData = evaluationRecordDAO.findListFromDoctByLevel(doctId, 2, start, limit);
                }
                break;
        }
        return dbData;
    }


    /**
     * 设置医生级别
     *
     * @param result
     * @param key
     * @throws ControllerException
     */
    private void setDoctLevel(Map<String, Object> result, String key) throws ControllerException {
        if (items == null) {
            Dictionary dic = organizationInfoService.queryDictionary(dicPath);
            items = dic.getSlice("", 3, "");
            if (items != null && items.size() > 0) {
                for (DictionaryItem item : items) {
                    if (item.getKey().equals(key)) {
                        result.put("doctLevel", item.getText());
                        break;
                    }
                }
            }
        } else {
            for (DictionaryItem item : items) {
                if (item.getKey().equals(key)) {
                    result.put("doctLevel", item.getText());
                    break;
                }
            }
        }
    }


    public EvaluationDefineDAO getEvaluationDefineDAO() {
        return evaluationDefineDAO;
    }

    public void setEvaluationDefineDAO(EvaluationDefineDAO evaluationDefineDAO) {
        this.evaluationDefineDAO = evaluationDefineDAO;
    }

    public EvaluationImpressDAO getEvaluationImpressDAO() {
        return evaluationImpressDAO;
    }

    public void setEvaluationImpressDAO(EvaluationImpressDAO evaluationImpressDAO) {
        this.evaluationImpressDAO = evaluationImpressDAO;
    }

    public EvaluationItemDAO getEvaluationItemDAO() {
        return evaluationItemDAO;
    }

    public void setEvaluationItemDAO(EvaluationItemDAO evaluationItemDAO) {
        this.evaluationItemDAO = evaluationItemDAO;
    }

    public EvaluationItemRecordDAO getEvaluationItemRecordDAO() {
        return evaluationItemRecordDAO;
    }

    public void setEvaluationItemRecordDAO(
            EvaluationItemRecordDAO evaluationItemRecordDAO) {
        this.evaluationItemRecordDAO = evaluationItemRecordDAO;
    }

    public EvaluationRecordDAO getEvaluationRecordDAO() {
        return evaluationRecordDAO;
    }

    public void setEvaluationRecordDAO(EvaluationRecordDAO evaluationRecordDAO) {
        this.evaluationRecordDAO = evaluationRecordDAO;
    }


}
